#include "aircraftmap.h"
using namespace FsxSimConnect;

//
// Map of Aircrafts
//
AircraftMap::AircraftMap() : QMap<SIMCONNECT_OBJECT_ID, Aircraft>()
{
    // code goes here
}

//
// Init by other map
//
AircraftMap::AircraftMap(const AircraftMap &otherMap): QMap<SIMCONNECT_OBJECT_ID, Aircraft>()
{
    AircraftMap::initByOtherMap(otherMap);
}

//
// Constructor by other aircrafts
//
AircraftMap::AircraftMap(const QList<Aircraft> &otherAircrafts) : QMap<SIMCONNECT_OBJECT_ID, Aircraft>()
{
    AircraftMap::initByOtherList(otherAircrafts);
}

//
// Assignment
//
AircraftMap &AircraftMap::operator =(const AircraftMap &otherMap)
{
    // Check for self-assignment!
    if (this == &otherMap)  return *this; // Same object? Yes, so skip assignment, and just return *this
    this->initByOtherMap(otherMap);
    return *this;
}

//
// Init by another map.
//
void AircraftMap::initByOtherMap(const AircraftMap &otherMap)
{
    QList<Aircraft> otherAircrafts = otherMap.values();
    AircraftMap::initByOtherList(otherAircrafts);
}

//
// Init by other Aircrafts
//
void AircraftMap::initByOtherList(const QList<Aircraft> otherAircrafts) {
    QMutexLocker locker(&_mutex);
    int c = otherAircrafts.count();
    for (int i=0; i<c; i++) {
        Aircraft a = otherAircrafts.at(i);
        AircraftMap::insert(a.getId(), a);
    }
}

//
// Add or update
//
void AircraftMap::addOrUpdateById(const SIMCONNECT_OBJECT_ID id, const FSXAircraftStringAndMiscData aircraftData)
{
    QMutexLocker locker(&_mutex);
    Aircraft a= AircraftMap::contains(id) ? AircraftMap::value(id) : Aircraft(id);
    a.setStringMiscData(aircraftData);

    // workaround, fix heli info
    QString category = QString(a.getStringMiscData().category);
    a.setHelicopter(category.startsWith("heli", Qt::CaseInsensitive));
    AircraftMap::insert(id, a);
}

//
// Add or update
//
void AircraftMap::addOrUpdateById(const SIMCONNECT_OBJECT_ID id, const FSXAircraftPositionAndSpeedData aircraftData, const int maxWaypoints, const qint64 timeFrameMs)
{
    QMutexLocker locker(&_mutex);
    Aircraft a= AircraftMap::contains(id) ? AircraftMap::value(id) : Aircraft(id);
    a.setPositionSpeedData(aircraftData, maxWaypoints, timeFrameMs);
    AircraftMap::insert(id, a);
}

//
// Add or update
//
void AircraftMap::addOrUpdateById(const SIMCONNECT_OBJECT_ID id, const FSXAircraftInstrumentationData aircraftData, const int maxWaypoints, const qint64 timeFrameMs)
{
    QMutexLocker locker(&_mutex);
    Aircraft a= AircraftMap::contains(id) ? AircraftMap::value(id) : Aircraft(id);
    a.setInstrumentationData(aircraftData, maxWaypoints, timeFrameMs);
    AircraftMap::insert(id, a);
}

//
// Add or update
//
void AircraftMap::addOrUpdateById(const SIMCONNECT_OBJECT_ID id, const FSXAircraftAvionicsData aircraftData)
{
    QMutexLocker locker(&_mutex);
    Aircraft a= AircraftMap::contains(id) ? AircraftMap::value(id) : Aircraft(id);
    a.setAvionicsData(aircraftData);
    AircraftMap::insert(id, a);
}

//
// JSON representation
//
QString AircraftMap::toJsonArray(const int level, const JsonParameter &parameter) const {
    const QString ind = JsonMarkupHelper::Indention(level);
    const QString indp1 = JsonMarkupHelper::Indention(level+1);
    QString j = ind + "[\n";
    QList<Aircraft> aircrafts = AircraftMap::values();
    int c = aircrafts.count();
    for(int i=0; i<c; i++)
    {
        Aircraft a = aircrafts.at(i);
        j += a.toJson(level + 1, parameter);
        j += (i+1) < c ? indp1 + ",\n" : "";
    }
    j += ind + "]\n";
    return j;
}

//
// HTML table representation
//
QString AircraftMap::toHtmlTable(const int level) const {
    const QList<Aircraft> aircrafts = AircraftMap::values();
    int c = aircrafts.count();
    if (c<1) return "";
    const QString ind = JsonMarkupHelper::Indention(level);
    const QString indp1 = JsonMarkupHelper::Indention(level+1);
    QString html = ind + "<table>\n";
    for(int i=0; i<c; i++)
    {
        Aircraft ap = aircrafts.at(i);
        html += ap.toHtmlTableRow(level + 1, i==0);
        html += (i+1) < c ? indp1 + "\n" : "";
    }
    html += ind + "</table>\n";
    return html;
}
